using System.Collections.Generic;
using Sixeyed.CodeGeneration.Metadata.Enums;
using Sixeyed.CodeGeneration.Metadata.Interfaces;

namespace Sixeyed.CodeGeneration.Metadata.Bases
{
    /// <summary>
    /// Abstract base class for metadata providers
    /// </summary>
    /// <typeparam name="TSource">Type of the metadata source</typeparam>
    public abstract class ProviderBase<TSource> : IMetadataProvider
        where TSource : IMetadataSource
    {
        #region Abstract members

        /// <summary>
        /// Unique name for the metatadata provider
        /// </summary>
        public abstract string Name { get;}

        /// <summary>
        /// Description of the provider
        /// </summary>
        public abstract string Description { get;}

        /// <summary>
        /// Type name for items returned by the provider
        /// </summary>
        public abstract string ItemTypeName { get;}

        /// <summary>
        /// Type name for source used by the provider
        /// </summary>
        public abstract string SourceTypeName { get; }

        /// <summary>
        /// Gets the name of all items available from the provider
        /// </summary>
        /// <returns></returns>
        public abstract List<string> GetItemNames();

        /// <summary>
        /// Gets the metadata item with the given key
        /// </summary>
        /// <param name="itemKey">Metadata item key</param>
        /// <returns>Metadata item</returns>
        public abstract IMetadataItem GetItem(string itemKey);

        #endregion

        #region Protected instance members

        /// <summary>
        /// Metadata source
        /// </summary>
        protected TSource _source;

        /// <summary>
        /// Instantiates and populates a new metadata item
        /// </summary>
        /// <typeparam name="TItem">IMetadataItem type</typeparam>
        /// <param name="itemKey">Unique key for the item</param>
        /// <returns>Populated metatdata item</returns>
        protected TItem CreateItem<TItem>(string itemKey)
            where TItem : IMetadataItem, new()
        {
            TItem item = new TItem();
            item.Key = itemKey;
            item.Provider = this;
            return item;
        }

        #endregion

        #region Public properties

        /// <summary>
        /// Gets the name of the valid source for the provider
        /// </summary>
        public virtual string SourceName
        {
            get { return string.Empty; }
        }

        /// <summary>
        /// Type of item selection the provider returns
        /// </summary>
        public virtual ProviderSelectionType SelectionType
        {
            //default to collection:
            get { return ProviderSelectionType.Collection; }
        }

        /// <summary>
        /// Metadata source for the provider
        /// </summary>
        public IMetadataSource Source
        {
            get { return this._source; }
            set { this._source = (TSource) value; }
        }

        /// <summary>
        /// Typed metadata source
        /// </summary>
        public TSource TypedSource
        {
            get { return this._source; }
            set { this._source = value; }
        }

        #endregion
    }
}
